#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>

#include "headers.h"
#include "tags.h"
#include "globals.h"
#include "stack.h"
#include "bytecode.h"
#include "vm.h"

// TESTS
void t_hdr();
void t_tag();
void t_stk();
// END TESTS

#define BYTECODE_SIZE (1 << 18)

int main(int argc, char **argv) {
  //t_hdr();
  //t_tag();
  //t_stk();
  
  char *filename;
  struct stat st;
  int fd;
  int code_length;

  if(argc != 2) {
    fprintf(stderr, "Usage: ./bytecode <filename>.byte\n");
    return -1;
  }

  filename = argv[1];

  fd = open(filename, O_RDONLY);
  if(fd == -1) {
    fprintf(stderr, "Could not open bytecode file %s\n", filename);
    return -1;
  }
  
  if(stat(filename, &st) == -1) {
    fprintf(stderr, "Could not stat bytecode file %s\n", filename);
    return -1;
  }
  
  code_length = st.st_size;
  if(code_length > BYTECODE_SIZE) {
    fprintf(stderr, "Not enough space for bytecode\n");
    return -1;
  }
  
  bytecode = mmap(NULL, BYTECODE_SIZE, PROT_READ, MAP_PRIVATE, fd, 0);
  if(bytecode == MAP_FAILED) {
    fprintf(stderr, "Memory mapping bytecode failed\n");
    return -1;
  }
  
  execute();
  
  return 0;
}
